﻿using FlyingHat.Common.Helper;
using FlyingHat.Core.Entities;
using FlyingHat.Model.Models.Global;
using FlyingHat.Service.IService;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FlyingHat.Extensions.Filter
{
    public class CustomerExceptionFilter : IAsyncExceptionFilter
    {
        private readonly ILogService logService;
        public CustomerExceptionFilter(ILogService logService)
        {
            this.logService = logService;
        }
        public async Task OnExceptionAsync(ExceptionContext context)
        {
            try
            {
                if (context != null && context.ExceptionHandled == false)
                {
                    // 加入日志
                    await logService.AddReturnIdAsync(new Log
                    {
                        Name = "全局捕获",
                        Level = "Error",
                        Message = context.Exception.Message,
                        IP = context.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "",
                        Exception = SerializeHelper.Serialize(context.Exception),
                    });
                    // 表示异常已经处理，其他外层捕获器无需处理
                    context.ExceptionHandled = true;
                    #region 判断是否是Ajax
                    var ajax = context.HttpContext.Request.Headers.ContainsKey("x-requested-with");
                    if (ajax)
                    {
                        context.Result = new JsonResult(ReturnModel.Fail(context.Exception.Message));
                    }
                    else
                    {
                        context.Result = new RedirectToActionResult("Error", "Error", new { error = context.Exception.Message });
                    }

                    #endregion
                }
            }
            catch
            {
                // 设置未处理 异常抛出到管道
                context.ExceptionHandled = false;
                // 此处如果不写 throw 那么抛出的错误是上一个错误，这样会找不到错误信息的，所以这里抛出当前错误，
                // 解决当前错误后再解决上一个错误
                throw;
            }
        }
    }
}
